package com.yzg.cas;

import java.util.LinkedList;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * @author misterWei
 * @create 2020年05月23号:23点20分
 * @mailbox forcontinue@163.com
 *
 * 1. 带锁方式实现共享变量原子性操作
 */
public class CasVariable {

    public static void main(String[] args) {
        Account account = new LockAccount(10000);
        account.test(account);
        System.out.println(account.getAccount());
    }



   public interface Account{
        int getAccount();
        void optionAccount(int account);

        default void test(Account account){
            // 测试 1000 并发量
            int threadNum = 1000;

            CyclicBarrier cyclicBarrier = new CyclicBarrier(threadNum);
            LinkedList<Thread> linkedList = new LinkedList();
            for (int i = 0; i < threadNum; i++) {
                Thread thread = new Thread(() -> {
                    try {
                        //模拟并发
                        cyclicBarrier.await();
                        account.optionAccount(10);
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }, i + " thread");
                linkedList.addLast(thread);
            }
            linkedList.forEach(thread -> {
                thread.start();
            });
                linkedList.forEach(thread -> {
                    try {
                        thread.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });


        }

    }

    /**
     * 带锁方式实现
     */
    static class LockAccount implements Account{
        int account;

        public LockAccount(int account) {
            this.account = account;
        }

        @Override
        public  int getAccount() {
            return this.account;
        }

        @Override
        public synchronized void optionAccount(int account) {
        this.account -= account;
        }
    }

}
